/*
 * AS_KICKUSER.cpp
 *
 *  Created on: 2014. 1. 20.
 *      Author: jjaehuny
 */


#include "../../User.h"
#include "../../Proxy.h"
#include "../../Command.h"
#include "../../NLogic/Space.h"
#include "../../NLogic/Battle.h"

namespace ProjectZ { namespace NCommand {

void SendFailKickUser(User * pUser)
{
	::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
	*pAck << static_cast<int16_t>(0);
	pAck->MakePacket(CMD_SA_KICKUSER);
	pUser->Send(pAck);
}

void Command::AS_KICKUSER(User * pUser, ::Network::Packet * pPacket)
{
	PREPARE_PACKET;

	int32_t userSeq = 0;
	* pPacket >> userSeq;

	User * pKickUser = NProxy::GetUser(userSeq);
	if (NULL == pKickUser)
	{
		DEBUGLOG("%s : NOT FOUND USER! userseq=%d", __FUNCTION__, userSeq);
		SendFailKickUser(pUser);
		return;
	}

	if (0 == pKickUser->GetRefCount())
	{
		DEBUGLOG("%s userSeq : %d UserState : %s enumstate : %d GID : %d", __FUNCTION__, userSeq, pKickUser->GetState()->GetName().c_str(), pKickUser->GetEnumState()
						, pKickUser->GetUserSeq());

		if (userSeq != pKickUser->GetUserSeq())
		{
			::ProjectZ::NProxy::RemoveUser(userSeq);

			::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
			*pAck << static_cast<int16_t>(ACK_OK);
			pAck->MakePacket(CMD_SA_KICKUSER);
			pUser->Send(pAck);

			//::ProjectZ::User::Factory::Instance().DEL(pKickUser);
			return;
		}

		pKickUser->FlushUserInfo();
		pKickUser->FlushCharacterInfo();
		pKickUser->UnRegistLocation();

		::ProjectZ::NProxy::Final(pKickUser);
		::ProjectZ::User::Factory::Instance().DEL(pKickUser);

		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		*pAck << static_cast<int16_t>(ACK_OK);
		pAck->MakePacket(CMD_SA_KICKUSER);
		pUser->Send(pAck);

		return;
	}

	if (2 <= pKickUser->GetRefCount() || 0 >= pKickUser->GetRefCount())
	{
		DEBUGLOG("%s : Maybe User is Battle Status! userseq=%d, refcount=%d", __FUNCTION__, userSeq, pKickUser->GetRefCount());
		SendFailKickUser(pUser);
		return;
	}


	NLogic::Space * pSpace = pKickUser->GetSpace();
	if (NULL != pSpace)
	{
		User * pOppUser = pKickUser->GetBattle()->GetData()._pvpOppUser;

		if (NULL != pOppUser)
		{
			if (pKickUser == pOppUser->GetBattle()->GetData()._pvpOppUser)
			{
				NLogic::Space * pOppSpace = pOppUser->GetSpace();
				if (NULL != pOppSpace  && (pOppSpace->GetData()._spaceType == NLogic::Space::SpaceType::PVP_USER
						|| pOppSpace->GetData()._spaceType == NLogic::Space::SpaceType::NEW_PVP_ROOM) )
				{
					pOppSpace->LeaveUser(pOppUser);

					pOppUser->GetBattle()->GetData().x		= ConstPosX;
					pOppUser->GetBattle()->GetData().y		= ConstPosY;
					pOppUser->GetBattle()->GetData().degree = ConstDegree;
					pOppUser->GetBattle()->GetData().bReadyFight = false;
					pOppUser->GetBattle()->GetData().bRecvEnterRoom = false;

					::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();

					*pAck << static_cast<int16_t>(ACK_MATCHING_MASTER_GONE);
					*pAck << pOppUser->GetUserSeq();
					*pAck << static_cast<uint16_t>(1);			// exit_map_id(?)
					*pAck << static_cast<uint16_t>(pOppUser->GetBattle()->GetData().x);
					*pAck << static_cast<uint16_t>(pOppUser->GetBattle()->GetData().y);
					*pAck << static_cast<uint16_t>(pOppUser->GetBattle()->GetData().degree);

					pAck->MakePacket(CMD_SC_PVP_OUT_REQ);
					pOppUser->Send(pAck);

//					pOppUser->GetBattle()->GetData()._pvpOppUser = NULL;
				}
			}
		}

//		if (NULL != pUser->GetSession()) { pUser->GetSession()->Close(); }
//		pKickUser->DecreaseRefCount();

		pKickUser->ForceCleanUp();

		DEBUGLOG("%s : User Kick!!! userseq=%d", __FUNCTION__, userSeq);

		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		*pAck << static_cast<int16_t>(ACK_OK);
		pAck->MakePacket(CMD_SA_KICKUSER);
		pUser->Send(pAck);
	}
	else
	{
//		if (NULL != pUser->GetSession()) { pUser->GetSession()->Close(); }
//
//		pKickUser->DecreaseRefCount();

		pKickUser->ForceCleanUp();

		::Network::Packet * pAck = ::Network::GETPACKETPOOL()->SEND_NEW();
		*pAck << static_cast<int16_t>(ACK_OK);
		pAck->MakePacket(CMD_SA_KICKUSER);
		pUser->Send(pAck);

		//SendFailKickUser(pUser);
	}
}

} /*NCommand*/ } /*ProjectZ*/




